import rich
from celery import Celery
from flask import Flask, jsonify
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from pydantic import ValidationError

from src.config.settings import settings

from .extentions.setup_logging import setup_logging

db = SQLAlchemy()
migrate = Migrate()
setup_logging()


def creat_celery_app(app: Flask) -> Celery:
    celery_app = Celery("tasks", broker=settings.CELERY_BROKER_URL, backend=settings.CELERY_RESULT_BACKEND)
    app.extensions["celery"] = celery_app
    return celery_app


def create_app():
    """创建 Flask 应用工厂函数"""
    app = Flask(__name__)
    # celery_app = creat_celery_app(app)
    # 配置
    app.config["SECRET_KEY"] = settings.SECRET_KEY
    app.config["DEBUG"] = settings.DEBUG
    app.config["SQLALCHEMY_DATABASE_URI"] = settings.database_url
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

    # 初始化扩展
    db.init_app(app)
    migrate.init_app(app, db)

    # 注册蓝图
    from src.api.base_meta_data import base_meta_data_bp
    from src.api.credit_cards import credit_bp
    from src.api.routes import api_bp

    app.register_blueprint(api_bp, url_prefix="/api")
    app.register_blueprint(credit_bp)
    app.register_blueprint(base_meta_data_bp)

    for rule in app.url_map.iter_rules():
        # print(f"路由注册: {rule.endpoint}, Route: {rule}")
        rich.print(f"路由注册: {rule}")
        # rich.print(rule.endpoint, rule)

    @app.errorhandler(Exception)
    def handle_exception(e):
        # 这里可以自定义日志、返回格式等
        import traceback

        print("全局异常捕获:", e)
        traceback.print_exc()
        if isinstance(e, ValidationError):
            # 格式化错误信息
            errors = []
            for error in e.errors():
                field = ".".join(str(loc) for loc in error["loc"])
                message = error["msg"]
                errors.append(f"字段'{field}': {message}")

            return (
                jsonify({"success": False, "error": "Check Error", "errMsg": "请求参数不符合要求", "details": errors}),
                400,
                {"Content-Type": "application/json; charset=utf-8"},
            )
        return (
            jsonify({"success": False, "error": "Internal Error", "message": str(e)}),
            500,
            {"Content-Type": "application/json; charset=utf-8"},
        )

    return app
